import 'dart:convert';
import 'dart:io';
import 'package:flustars/flustars.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:management/app/api.dart';
import 'package:management/model/msc_model.dart';
import 'package:management/model/open_gate_record_model.dart';
import 'package:management/model/user_model.dart';
import 'package:management/model/visitor_model.dart';
import 'package:management/utils/http_utils.dart';
import 'package:management/utils/log_utils.dart';
import 'package:sqflite/sqflite.dart';

final String dbName = 'management.db';

final String tableGate = "gate";

///设备名称（通道名称）
final String columnGateName = "deviceName";

///设备ID
final String columnDeviceId = "deviceId";

///部门ID
final String columnDepartmentId = "departmentID";

@deprecated
final String columnInterface = 'interface';

final String columnGateMac = 'mac';

///开闸结果回调
typedef OpenGateResultCallback = void Function(
    OpenGateResultModel openGateResultModel);

class GateModel {
  GateModel(this.deviceName, this.deviceId, this.departmentId, this.mac);

  ///设备名称
  String? deviceName;

  ///设备接口
  @deprecated
  String? deviceInterface;

  ///设备ID
  String? deviceId;

  ///部门ID(场地ID)
  String? departmentId;

  ///设备类型
  int? type;

  ///设备MAC地址
  String? mac;

  Map<String, Object?> toMap() {
    var map = <String, Object?>{
      columnGateName: deviceName,
      columnGateMac: mac,
      columnDeviceId: deviceId,
      columnDepartmentId: departmentId,
    };
    return map;
  }

  GateModel.formMap(Map<String, Object?> map) {
    deviceName = map[columnGateName] as String?;
    mac = map[columnGateMac] as String?;
    deviceId = map[columnDeviceId] as String?;
    departmentId = map[columnDepartmentId] as String?;
  }

  /// 人脸相机开闸
  ///
  /// [gateRecordModel] 开闸成功则在数据库插入开闸记录
  ///
  /// [openGateResultCallback] 用来处理开闸失败结果信息
  void openFaceGate({
    bool showSuccessToast = true,
    bool showFailToast = true,
    GateRecordModel? gateRecordModel,
    void openGateResultCallback(OpenGateResultModel resultModel)?,
  }) async {
    //开闸结果
    bool openGateResult = false;
    //开闸失败原因
    String failMessage = "";
    if (TextUtil.isEmpty(FaceApi.faceToken)) {
      User? user =
          await UserProvider.instance.queryName(SpUtil.getString("userName")!);
      FaceApi.faceToken = user!.faceToken;
    }

    // MyLog.d("FaceApi.faceToken: ${FaceApi.faceToken}");
    HttpUtil.get(
        url:
            "http://cyai.cytingchechang.com/os/v1/ai/aiApp/openRelay/$deviceId/$departmentId",
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
          'AdminToken': FaceApi.faceToken!
        },
        onSuccess: (msg) {
          MyLog.i(msg.toString());
          Map convert = JsonDecoder().convert(msg.toString());
          // MyLog.w("convert: $convert" "${convert is Map}");
          if (convert["code"] != -1) {
            if (gateRecordModel != null) {
              //开闸成功 并且 需要保存开闸记录
              GateRecordProvider.instance.insert(gateRecordModel);
            }
            if (showSuccessToast) {
              Fluttertoast.showToast(msg: msg.toString());
            }

            if (openGateResultCallback != null) {
              openGateResult = true;
              openGateResultCallback(OpenGateResultModel(
                  openGate: openGateResult, failMessage: failMessage));
            }
          } else {
            //e.g. {"code":-1,"message":"相机离线,操作失败"}
            MyLog.e(msg.toString());
            if (showFailToast) {
              Fluttertoast.showToast(msg: msg.toString());
            }

            if (openGateResultCallback != null) {
              openGateResult = false;
              failMessage = convert["message"];
              openGateResultCallback(
                OpenGateResultModel(
                  openGate: openGateResult,
                  failMessage: failMessage,
                ),
              );
            }
          }
        },
        onFail: (statusCode, responseBody) async {
          MyLog.e(" statusCode: $statusCode \n responseBody: $responseBody");
          String toastMsg = "";
          if (statusCode == 401) {
            toastMsg = "token已过期，请重新登录。";
            User? old = await UserProvider.instance
                .queryName(SpUtil.getString("userName")!);
            UserProvider.instance.update(
              old!,
              User(old.name, old.psw, faceToken: null),
            );
          }
          if (showFailToast) {
            Fluttertoast.showToast(msg: toastMsg);
          }

          if (openGateResultCallback != null) {
            openGateResult = false;
            var convert = JsonDecoder().convert(responseBody.toString());
            failMessage = convert["message"];
            openGateResultCallback(
              OpenGateResultModel(
                  openGate: openGateResult, failMessage: failMessage),
            );
          }
        });
  }

  /// 车牌识别相机开闸
  ///
  /// 畅盈一楼开闸接口 https://www.cytingchechang.com/os/v1/tcpToken/openDoor/6741
  void openLPRGate(String? doorId) async {
    // var response = await HttpUtil.client.post(Uri.parse(
    //     "https://www.cytingchechang.com/os/v1/tcpToken/openDoor/$doorId"));
    // await  ParkApi.loginParkCloud();
    var response = await HttpUtil.client.post(
      Uri.parse(ParkApi.park_host + "/os/v1/tcpToken/openDoor/$doorId"),
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'AdminToken': ParkApi.parkToken!,
        // "departmentId": "2057",
      },
      // body: JsonUtil.encodeObj({
      //   "tcpTokenId": int.parse(doorId),
      //   "userId": ParkApi.parkUserId,
      //   "userName": "btTest"
      // }),
    );
    MyLog.i(response.body);
    if (response.statusCode == HttpStatus.ok) {
      Fluttertoast.showToast(msg: "开闸成功");
    } else {
      Fluttertoast.showToast(msg: "开闸失败");
    }
  }
}

class GateProvider {
  Database? db;

  GateProvider._();

  static final GateProvider instance = GateProvider._();

  Future<int> insert(GateModel gateModel) async {
    await open();
    int count = await db!.insert(tableGate, gateModel.toMap());
    close();
    return count;
  }

  Future<List<GateModel>?> getAllGate() async {
    await open();
    List<Map<String, Object?>> maps =
        await db!.rawQuery('SELECT * from $tableGate');

    if (maps.length > 0) {
      List<GateModel> allGates = [];
      maps.forEach((element) {
        allGates.add(GateModel.formMap(element));
      });
      close();
      return allGates;
    }
    close();
    return null;
  }

  Future<GateModel?> queryByName(String gateName) async {
    await open();
    List<Map<String, Object?>> maps = await db!.query(tableGate,
        columns: [
          columnGateMac,
          columnGateName,
          columnDeviceId,
          columnDepartmentId
        ],
        where: "$columnGateName = ?",
        whereArgs: [gateName]);
    if (maps.length > 0) {
      close();
      return GateModel.formMap(maps.first);
    }
    close();
    return null;
  }

  Future<int> update(GateModel old, GateModel newGate) async {
    await open();
    int count = await db!.rawUpdate(
        "update $tableGate set $columnGateName = ? , $columnDeviceId = ? , $columnDepartmentId = ? , "
        "$columnGateMac = ? where $columnGateMac = ?",
        [
          newGate.deviceName,
          newGate.deviceId,
          newGate.departmentId,
          newGate.mac,
          old.mac
        ]);

    close();
    return count;
  }

  Future<int> delete(String name) async {
    await open();
    int count = await db!
        .delete(tableGate, where: "$columnGateName = ?", whereArgs: [name]);
    close();
    return count;
  }

  Future open() async {
    db = await openDatabase(dbPath!);

    ///关闭数据库
  }

  Future close() async => db!.close();
}
